package com.writing.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.writing.dto.AIGenerateRequest;
import com.writing.entity.ApiConfig;
import com.writing.service.AIService;
import com.writing.service.ApiConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * AI服务实现
 * 包装OpenAI API的调用，安全地管理API Key
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AIServiceImpl implements AIService {

    private final ApiConfigService apiConfigService;
    private final OkHttpClient httpClient = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(120, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .build();

    /**
     * 生成文本（非流式）
     */
    @Override
    public String generateText(AIGenerateRequest request) throws Exception {
        log.info("开始生成文本，类型：{}", request.getType());
        
        // 获取API配置（根据模型名称筛选）
        ApiConfig apiConfig = getApiConfig(request.getModel());
        if (apiConfig == null) {
            throw new RuntimeException("未找到可用的API配置，请检查后端设置");
        }

        // 构建请求体
        JSONObject requestBody = buildRequestBody(request);
        requestBody.put("stream", false);

        String url = buildUrl(apiConfig.getBaseUrl(), "/chat/completions");
        log.info("调用API: {}", url);

        // 发送请求
        RequestBody body = RequestBody.create(
                requestBody.toString(),
                MediaType.parse("application/json; charset=utf-8")
        );

        Request httpRequest = new Request.Builder()
                .url(url)
                .header("Authorization", "Bearer " + apiConfig.getApiKey())
                .header("Content-Type", "application/json")
                .post(body)
                .build();

        try (Response response = httpClient.newCall(httpRequest).execute()) {
            if (!response.isSuccessful()) {
                String errorBody = response.body() != null ? response.body().string() : "";
                log.error("API请求失败: {}, 错误信息: {}", response.code(), errorBody);
                throw new RuntimeException("API请求失败: " + response.code() + " - " + errorBody);
            }

            ResponseBody responseBody = response.body();
            if (responseBody == null) {
                throw new RuntimeException("API响应为空");
            }

            String responseStr = responseBody.string();
            log.debug("API响应: {}", responseStr);

            // 解析响应
            JSONObject responseJson = JSON.parseObject(responseStr);
            JSONArray choices = responseJson.getJSONArray("choices");
            
            if (choices == null || choices.size() == 0) {
                throw new RuntimeException("API响应格式错误：未找到choices");
            }

            String content = choices.getJSONObject(0).getJSONObject("message").getString("content");
            log.info("生成完成，内容长度: {}", content.length());

            return content;
        }
    }

    /**
     * 生成文本（流式）
     */
    @Override
    public void generateTextStream(AIGenerateRequest request, StreamCallback callback) throws Exception {
        log.info("开始流式生成文本，类型：{}", request.getType());
        
        // 获取API配置（根据模型名称筛选）
        ApiConfig apiConfig = getApiConfig(request.getModel());
        if (apiConfig == null) {
            callback.onError(new RuntimeException("未找到可用的API配置，请检查后端设置"));
            return;
        }

        // 构建请求体
        JSONObject requestBody = buildRequestBody(request);
        requestBody.put("stream", true);

        String url = buildUrl(apiConfig.getBaseUrl(), "/chat/completions");
        log.info("调用流式API: {}", url);

        // 发送请求
        RequestBody body = RequestBody.create(
                requestBody.toString(),
                MediaType.parse("application/json; charset=utf-8")
        );

        Request httpRequest = new Request.Builder()
                .url(url)
                .header("Authorization", "Bearer " + apiConfig.getApiKey())
                .header("Content-Type", "application/json")
                .post(body)
                .build();

        try {
            httpClient.newCall(httpRequest).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    log.error("流式请求失败", e);
                    callback.onError(e);
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    try {
                        if (!response.isSuccessful()) {
                            String errorBody = response.body() != null ? response.body().string() : "";
                            log.error("API请求失败: {}, 错误信息: {}", response.code(), errorBody);
                            callback.onError(new RuntimeException("API请求失败: " + response.code()));
                            return;
                        }

                        ResponseBody responseBody = response.body();
                        if (responseBody == null) {
                            callback.onError(new RuntimeException("API响应为空"));
                            return;
                        }

                        // 处理流式响应
                        try (BufferedReader reader = new BufferedReader(responseBody.charStream())) {
                            String line;
                            int chunkCount = 0;
                            while ((line = reader.readLine()) != null) {
                                if (line.trim().isEmpty()) {
                                    continue;
                                }

                                if (line.startsWith("data: ")) {
                                    String data = line.substring(6).trim();

                                    if ("[DONE]".equals(data)) {
                                        log.info("流式传输完成，总chunks: {}", chunkCount);
                                        callback.onComplete();
                                        break;
                                    }

                                    if (!data.isEmpty()) {
                                        try {
                                            JSONObject chunk = JSON.parseObject(data);
                                            
                                            // 检查是否有 finish_reason，如果有则完成
                                            JSONArray choices = chunk.getJSONArray("choices");
                                            if (choices != null && choices.size() > 0) {
                                                JSONObject choice = choices.getJSONObject(0);
                                                String finishReason = choice.getString("finish_reason");
                                                if (finishReason != null && !finishReason.isEmpty()) {
                                                    log.info("收到完成标记: {}", finishReason);
                                                    callback.onComplete();
                                                    break;
                                                }
                                            }
                                            
                                            String content = extractContent(chunk);
                                            if (content != null && !content.isEmpty()) {
                                                callback.onChunk(content);
                                                chunkCount++;
                                            }
                                        } catch (Exception e) {
                                            log.warn("解析chunk失败: {}", data.length() > 200 ? data.substring(0, 200) + "..." : data, e);
                                        }
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("处理流式响应失败", e);
                        callback.onError(e);
                    }
                }
            });
        } catch (Exception e) {
            log.error("发送流式请求失败", e);
            callback.onError(e);
        }
    }

    /**
     * 验证API配置
     */
    @Override
    public boolean validateApiConfig(String baseUrl, String apiKey) throws Exception {
        String url = buildUrl(baseUrl, "/models");
        log.info("验证API配置: {}", url);

        Request request = new Request.Builder()
                .url(url)
                .header("Authorization", "Bearer " + apiKey)
                .get()
                .build();

        try (Response response = httpClient.newCall(request).execute()) {
            boolean isValid = response.isSuccessful();
            log.info("API配置验证结果: {}", isValid ? "成功" : "失败 (" + response.code() + ")");
            return isValid;
        }
    }

    /**
     * 获取API配置（根据模型名称筛选）
     * 
     * @param modelName 模型名称，如果为null或空，则返回第一个启用的配置
     * @return 匹配的API配置，如果未找到则返回null
     */
    private ApiConfig getApiConfig(String modelName) {
        List<ApiConfig> configs = apiConfigService.getEnabledConfigs();
        if (configs.isEmpty()) {
            log.warn("未找到启用的API配置");
            return null;
        }
        
        // 如果指定了模型名称，尝试找到匹配的配置
        if (modelName != null && !modelName.trim().isEmpty()) {
            String modelNameTrimmed = modelName.trim();
            log.info("查找支持模型 '{}' 的API配置", modelNameTrimmed);
            
            // 优先查找 selectedModel 匹配的配置
            for (ApiConfig config : configs) {
                if (config.getSelectedModel() != null && 
                    config.getSelectedModel().trim().equalsIgnoreCase(modelNameTrimmed)) {
                    log.info("找到匹配的API配置: {} (模型: {})", config.getName(), config.getSelectedModel());
                    return config;
                }
            }
            
            // 如果没有找到匹配的，记录警告并使用第一个配置
            log.warn("未找到支持模型 '{}' 的API配置，使用第一个启用的配置: {}", 
                    modelNameTrimmed, configs.get(0).getName());
        }
        
        // 如果没有指定模型名称，或者没有找到匹配的，返回第一个启用的配置
        ApiConfig defaultConfig = configs.get(0);
        log.info("使用默认API配置: {} (模型: {})", 
                defaultConfig.getName(), 
                defaultConfig.getSelectedModel() != null ? defaultConfig.getSelectedModel() : "未指定");
        return defaultConfig;
    }

    /**
     * 构建请求体
     */
    private JSONObject buildRequestBody(AIGenerateRequest request) {
        JSONObject requestBody = new JSONObject();
        
        requestBody.put("model", request.getModel());
        
        // 构建消息列表
        JSONArray messages = new JSONArray();
        
        // 添加系统提示词
        if (request.getSystemPrompt() != null && !request.getSystemPrompt().isEmpty()) {
            JSONObject systemMsg = new JSONObject();
            systemMsg.put("role", "system");
            systemMsg.put("content", request.getSystemPrompt());
            messages.add(systemMsg);
        }
        
        // 添加对话历史
        if (request.getMessages() != null && !request.getMessages().isEmpty()) {
            for (AIGenerateRequest.Message msg : request.getMessages()) {
                JSONObject msgObj = new JSONObject();
                msgObj.put("role", msg.getRole());
                msgObj.put("content", msg.getContent());
                messages.add(msgObj);
            }
        }
        
        // 如果只有prompt，添加为用户消息
        if ((request.getMessages() == null || request.getMessages().isEmpty()) && 
            request.getPrompt() != null) {
            JSONObject userMsg = new JSONObject();
            userMsg.put("role", "user");
            userMsg.put("content", request.getPrompt());
            messages.add(userMsg);
        }
        
        requestBody.put("messages", messages);
        
        // 添加可选参数
        if (request.getMaxTokens() != null && request.getMaxTokens() > 0) {
            requestBody.put("max_tokens", request.getMaxTokens());
        }
        
        if (request.getTemperature() != null) {
            requestBody.put("temperature", request.getTemperature());
        } else {
            requestBody.put("temperature", 0.7);
        }
        
        if (request.getTopP() != null) {
            requestBody.put("top_p", request.getTopP());
        }
        
        if (request.getFrequencyPenalty() != null) {
            requestBody.put("frequency_penalty", request.getFrequencyPenalty());
        }
        
        if (request.getPresencePenalty() != null) {
            requestBody.put("presence_penalty", request.getPresencePenalty());
        }
        
        return requestBody;
    }

    /**
     * 提取内容
     */
    private String extractContent(JSONObject chunk) {
        try {
            JSONArray choices = chunk.getJSONArray("choices");
            if (choices != null && choices.size() > 0) {
                JSONObject choice = choices.getJSONObject(0);
                
                // 检查是否有 finish_reason，如果有且不为 null，说明已完成
                String finishReason = choice.getString("finish_reason");
                if (finishReason != null && !finishReason.isEmpty()) {
                    // 已完成，返回空字符串表示结束
                    return null;
                }
                
                // 尝试获取 delta.content
                JSONObject delta = choice.getJSONObject("delta");
                if (delta != null) {
                    String content = delta.getString("content");
                    // content 可能为 null，这是正常的（某些 chunk 只包含 metadata）
                    return content != null ? content : "";
                }
            }
        } catch (Exception e) {
            log.debug("提取内容失败", e);
        }
        return null;
    }

    /**
     * 构建URL
     */
    private String buildUrl(String baseUrl, String endpoint) {
        baseUrl = baseUrl.trim();
        while (baseUrl.endsWith("/")) {
            baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
        }

        if (baseUrl.endsWith("/v1")) {
            // 如果baseUrl已经以/v1结尾
            if (endpoint.startsWith("/v1")) {
                return baseUrl + endpoint.substring(3);
            } else {
                return baseUrl + endpoint;
            }
        } else {
            // 否则拼接 /v1 前缀
            if (endpoint.startsWith("/v1")) {
                return baseUrl + endpoint;
            } else {
                return baseUrl + "/v1" + endpoint;
            }
        }
    }
}

